/**
 * Created by IntelliJ IDEA.
 * User: newzhq
 * Date: 13-6-29
 * Time: 上午6:23
 * To change this template use File | Settings | File Templates.
 */
(function ($) {
    //创建隐藏域，并赋值，冗余当前值在原对象上
    function setValue($target, value, text) {
        $target.$div.append(createValue($target.$opts.inputname, value, text));
        $target.val(value);
    }

    //创建隐藏域
    function createValue(name, value, text) {
        return $('<input type="hidden" />').attr("name", name).attr("_text",text).val(value);
    }

    //设置展示值，容易当前展示值在原对象上
    function setText($target, value) {
        if (!value && value == "") return;
        clearToolTip($target);
        $target.$input.val(value);
        $target.attr("_text",value);
    }

    //取得text;
    function getText($target) {
        return $target.attr("_text");
    }

    //设置选中值
    function setMap($target, value, text) {
        clear($target);
        if ((!value || value == "") && (!text || text == "")) {
            setToolTip($target);
            return;
        }
        setValue($target, value, text);
        setText($target, text);
    }

    //触发选中回调
    function select($target, value, text) {
        setMap($target, value, text);
        if (typeof value == 'object') {
            $target.$opts.onSelect(value);
            return;
        }
        var data = {}
        data[$target.$opts.valueField] = value;
        data[$target.$opts.textField] = text;
        $target.$opts.onSelect(data);
    }

    function clear($target) {
        $target.val("");
        $target.attr("_text","");
        $target.$input.val("");
        $target.$div.find(":hidden").remove();
        $target.$opts.onClear($target);
        setToolTip($target);
    }

    function setToolTip($target) {
        var defaultstr = $target.$opts.defaultstr.replace("(0)", $target.$opts.keylength);
        $target.$input.css("font-style", "italic").css("font-size", 12).css("color", "#808080").val(defaultstr);
    }

    function clearToolTip($target) {
        $target.$input.css("font-style", "").css("font-size", "").css("color", "").val("");
    }

    function loadData($target, data) {
        clearData($target);
        createli($target, data);
        return $(data).length > 0
    }

    function clearData($target) {
        clearli($target);
    }

    function clearli($target) {
        $target.$ul.empty();
    }

    function createli($target, data) {
        $(data).each(function (index) {
            if (index >= 10) return;
            var $li = $('<li class="ui-menu-item"></li>').appendTo($target.$ul);
            $li.val(this[$target.$opts.valueField]).text(this[$target.$opts.textField]);
            liHandlder($target, $li);
        })
    }

    function liHandlder($target, $li) {
        $li.click(function () {
            select($target, $li.val(), $li.text());     //回调onSelect
            hideUl($target);
        });

        $li.mousemove(function () {
            $target.$ul.find("li").removeClass("hovers");
            $target.currentIndex = $(this).index();
            $(this).addClass("hovers");
        });
    }

    function showUl($target) {
        $target.currentIndex = -1;
        $target.$ul.show();
    }

    function hideUl($target) {
        $target.currentIndex = -1;
        $target.$ul.hide();
    }

    function refresh($target) {
        setTimeout(function () {
            hideUl($target);
            if ($target.$div.find(":hidden").length == 0) {
                setToolTip($target);
                return;
            }

            clearToolTip($target);
            $target.$input.val($target.$div.find(":hidden").attr("_text"));
        }, 300);
    }

    //从服务取数据
    function getServerData($target, condition) {
        var params = {};
        if ($target.$opts.param) {
            params[$target.$opts.param] = condition;
        }
        $.post($target.$opts.url, params, function (data) {
            //如果返回的数据的项目小于当前的缓存条数设置则进行缓存数据保存
            if (data.length <= $target.$opts.datalength) {
                $target.$opts.key = condition;
                $target.$opts.data = data;
            }

            initData($target, data);
        });
    }

    function initData($target, data) {
        if (loadData($target, data)) {
            showUl($target);
        } else {
            hideUl($target);
        }
    }

    function getClientData($target, condition) {
        if ($target.$opts.data.length <= 0) {
            return;
        }

        var data = $($target.$opts.data).filter(function () {
            return this[$target.$opts.textField].indexOf(condition) > -1;
        });

        initData($target, data);
    }

    function save($target) {
        $target.data("zcombobox", $target);
    }

    function get($this) {
        return $this.data("zcombobox");
    }

    function setReadonly($target, readonly) {
        if (readonly) {
            $target.$input.attr("disabled", true);
            $target.$btn.hide();
        } else {
            $target.$input.attr("disabled", false);
            $target.$btn.show();
        }
    }

    //创建控件
    function create($target) {
        var $div = $('<div class="ui-autocomplete" />').width($target.width());
        var $input = $('<input class="ui-autocomplete-input" />').width($target.width()).appendTo($div);
        var $ul = $('<ul class="ui-menu" ></ul>').width($target.width()).hide();
        $target.removeAttr("name").hide().after($ul).after($div);
        $target.$div = $div;
        $target.$input = $input;
        $target.$input.blur(function () {
            refresh($target);
        });
        $target.$input.focus(function () {
            clearToolTip($target);
            if (($target.$opts.keylength == 0) && ($target.$input.val() == "")) {
                lookupData($target, "");
            }
        });
        $target.$ul = $ul;
        $target.$btn = createBtn($target);
        $target.$btn.click(function () {
            clear($target);
        });
        setReadonly($target, $target.$opts.readonly);
        keyHandler($target);
        save($target);
        setMap($target, $target.$opts.selectData[$target.$opts.valueField], $target.$opts.selectData[$target.$opts.textField]);
        $target.$opts.onSuccess($target);
    }

    //创建按钮
    function createBtn($target) {
        return $('<input type="button" class="ui-autocomplete-button" />')
            .css("top", ($target.$input.height() - 16) / 2)
            .css("left", $target.width() - 18).appendTo($target.$div);
    }

    //查询数据
    function lookupData($target, condition) {
        //判断当前查询查毒大于keylength
        if (condition.length >= $target.$opts.keylength) {
            //当前的输入框中的拼音跟之前缓存的拼音相同或更精确则从缓存去
            if (!($target.$opts.remote) || (condition.indexOf($target.$opts.key) > -1)) {
                //如果当前的输入框中的拼音跟之前缓存的拼音不相同则从服务器取，如果达到缓存的数量更新当前的缓存拼音，及数据
                getClientData($target, condition);
            } else {
                getServerData($target, condition);
            }
        }
    }

    function up($target, maxIndex) {
        if ($target.$ul.is(":hidden")) return;
        if ($target.currentIndex >= maxIndex) {
            $target.$ul.find("li").eq($target.currentIndex = 0).addClass("hovers");
        } else {
            $target.$ul.find("li").eq(++$target.currentIndex).addClass("hovers");
        }
    }

    function down($target, maxIndex) {
        if ($target.$ul.is(":hidden")) return;
        if ($target.currentIndex <= 0) {
            $target.$ul.find("li").eq($target.currentIndex = maxIndex).addClass("hovers");
        } else {
            $target.$ul.find("li").eq(--$target.currentIndex).addClass("hovers");
        }
    }

    function unSelect($target) {
        $target.$ul.find("li").removeClass("hovers");
        $target.currentIndex = -1;
    }

    function keyHandler($target) {
        $target.$input.keyup(function (e) {
            var maxIndex = $target.$ul.find("li").length - 1;
            if ($.inArray(e.which, [38, 40, 13, 27]) > -1) {
                $target.$ul.find("li").removeClass("hovers");
            } else {
                unSelect($target);
            }
            switch (e.which) {
                case 40:    //上
                    up($target, maxIndex);
                    break;
                case 38:
                    down($target, maxIndex);
                    break;
                case 13:
                    if ($target.$ul.is(":hidden") || $target.currentIndex == -1) {
                        lookupData($target, $target.$input.val());
                    } else {
                        if ($target.currentIndex != -1) {
                            var $li = $target.$ul.find("li").eq($target.currentIndex);
                            $li.click();
                        }
                        hideUl($target);
                    }
                    break;
                case 27:
                    hideUl($target);
                    break;
            }
        })
    }

    $.fn.zcombobox = function (options, param) {
        if (typeof options == 'string') {       //判断为调用方法
            if (get(this) == null) return this;
            var method = $.fn.zcombobox.methods[options];
            if (method) {
                return method(get(this), param);
            }
        } else {                                //判断为构造或传递参数
            if (get(this) == null) {
                $(this).each(function () {
                    var $target = $(this);
                    $target.$opts = $.extend({}, $.fn.zcombobox.defaults, options, {inputname:$target.attr("name")});
                    create($target);
                })
            } else {
                var $target = get(this);
                $target.$opts = $.extend($target.$opts, options);
            }
        }
    }

    $.fn.zcombobox.methods = {
        setMap:function ($target, data) {
            setMap($target, data[$target.$opts.valueField], data[$target.$opts.textField]);
        },
        getText:function ($target) {
            getText($target);
        },
        clear:function ($target) {
            clear($target);
        },
        loadData:function ($target, data) {
            loadData($target, $target.$opts.data = data)
        },
        setReadonly:function ($target, readonly) {
            setReadonly($target, $target.$opts.readonly = readonly);
        }
    }

    $.fn.zcombobox.defaults = {
        datalength:100, //缓存多少数量的数据（内部参数，保持默认）
        defaultstr:"查询输入(0)个字", //默认查询提示

        valueField:"value", //下拉的value
        textField:"text", //下拉的text
        keylength:0, //多少位按回车查询
        data:[], //下拉的数据源
        selectData:{}, //默认值
        param:null, //参数名称
        url:null, //数据源的url地址
        remote:true,
        readonly:false,
        onSuccess:function ($target) {
        }, //加载结束时
        onSelect:function (data) {
        },    //选择事件
        onClear:function ($target) {
        }   //清除数据时间
    }
})(jQuery)